﻿using FreeSql;
using Microsoft.Data.SqlClient;
using System.Data;
using System.Reflection;


namespace WebServer.Extensions;

internal static class InitcomDatabaseExtension
{
    private static string GetConnectionString(this FreeSqlBuilder @this)
    {
        Type type = @this.GetType();
        FieldInfo fieldInfo = type.GetField("_masterConnectionString", BindingFlags.NonPublic | BindingFlags.Instance);
        if (fieldInfo is null)
        {
            throw new ArgumentException("_masterConnectionString is null");
        }
        return fieldInfo.GetValue(@this).ToString();
    }

    public static FreeSqlBuilder CreateDatabaseIfNotExistsSqlServer(this FreeSqlBuilder @this, string connectionString = "")
    {
        FieldInfo dataTypeFieldInfo = @this.GetType().GetField("_dataType", BindingFlags.NonPublic | BindingFlags.Instance);
        DataType dbType = (DataType)dataTypeFieldInfo.GetValue(@this);

        if (dbType != DataType.SqlServer) return @this;

        if (connectionString == "")
        {
            connectionString = @this.GetConnectionString();
        }
        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString);
        string createDatabaseSql;
        if (!string.IsNullOrEmpty(builder.AttachDBFilename))
        {
            string fileName = ExpandFileName(builder.AttachDBFilename);
            string name = Path.GetFileNameWithoutExtension(fileName);
            string logFileName = Path.ChangeExtension(fileName, ".ldf");
            createDatabaseSql = @$"CREATE DATABASE {builder.InitialCatalog}   on  primary   
                (
                    name = '{name}',
                    filename = '{fileName}'
                )
                log on
                (
                    name= '{name}_log',
                    filename = '{logFileName}'
                )";
        }
        else
        {
            createDatabaseSql = @$"CREATE DATABASE {builder.InitialCatalog}";
        }

        using SqlConnection cnn = new SqlConnection($"Data Source={builder.DataSource};Integrated Security = True;User ID={builder.UserID};Password={builder.Password};Initial Catalog=master;Min pool size=1;Persist Security Info=True;TrustServerCertificate=True");
        cnn.Open();
        using SqlCommand cmd = cnn.CreateCommand();
        cmd.CommandText = $"select * from sysdatabases where name = '{builder.InitialCatalog}'";

        SqlDataAdapter apter = new SqlDataAdapter(cmd);
        DataSet ds = new DataSet();
        apter.Fill(ds);

        if (ds.Tables[0].Rows.Count == 0)
        {
            cmd.CommandText = createDatabaseSql;
            cmd.ExecuteNonQuery();
        }

        return @this;
    }

    private static string ExpandFileName(string fileName)
    {
        if (fileName.StartsWith("|DataDirectory|", StringComparison.OrdinalIgnoreCase))
        {
            var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
            if (string.IsNullOrEmpty(dataDirectory))
            {
                dataDirectory = AppDomain.CurrentDomain.BaseDirectory;
            }
            string name = fileName.Replace("\\", "").Replace("/", "").Substring("|DataDirectory|".Length);
            fileName = Path.Combine(dataDirectory, name);
        }
        if (!Directory.Exists(Path.GetDirectoryName(fileName)))
        {
            Directory.CreateDirectory(Path.GetDirectoryName(fileName));
        }
        return Path.GetFullPath(fileName);
    }
}
